<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="部署" tabindex="-1"><a class="header-anchor" href="#部署"><span>部署</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#server-requirements">服务器要求</a></li>
<li><a href="#server-configuration">服务器配置</a>
<ul>
<li><a href="#nginx">Nginx</a></li>
<li><a href="#frankenphp">FrankenPHP</a></li>
<li><a href="#directory-permissions">目录权限</a></li>
</ul>
</li>
<li><a href="#optimization">优化</a>
<ul>
<li><a href="#optimizing-configuration-loadin">配置缓存</a></li>
<li><a href="#caching-events">事件缓存</a></li>
<li><a href="#optimizing-route-loadin">路由缓存</a></li>
<li><a href="#optimizing-view-loading">视图缓存</a></li>
</ul>
</li>
<li><a href="#debug-mode">调试模式</a></li>
<li><a href="#the-health-route">健康检查路由</a></li>
<li><a href="#deploying-with-forge-or-vapor">使用 Forge 或 Vapor 轻松部署</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>当你准备将 Laravel 应用程序部署到生产环境时，有一些重要的步骤可以确保你的应用程序运行得尽可能高效。在本文档中，我们将涵盖一些确保 Laravel 应用程序正确部署的良好起点。</p>
<h2 id="服务器要求" tabindex="-1"><a class="header-anchor" href="#服务器要求"><span>服务器要求</span></a></h2>
<p>Laravel 框架有一些建议的系统要求。你应确保你的 Web 服务器至少具备以下 PHP 版本和扩展：</p>
<ul>
<li>PHP &gt;= 8.2</li>
<li>Ctype PHP 扩展</li>
<li>cURL PHP 扩展</li>
<li>DOM PHP 扩展</li>
<li>Fileinfo PHP 扩展</li>
<li>Filter PHP 扩展</li>
<li>Hash PHP 扩展</li>
<li>Mbstring PHP 扩展</li>
<li>OpenSSL PHP 扩展</li>
<li>PCRE PHP 扩展</li>
<li>PDO PHP 扩展</li>
<li>Session PHP 扩展</li>
<li>Tokenizer PHP 扩展</li>
<li>XML PHP 扩展</li>
</ul>
<h2 id="服务器配置" tabindex="-1"><a class="header-anchor" href="#服务器配置"><span>服务器配置</span></a></h2>
<h3 id="nginx" tabindex="-1"><a class="header-anchor" href="#nginx"><span>Nginx</span></a></h3>
<p>如果你正在将应用程序部署到运行 Nginx 的服务器上，你可以使用以下配置文件作为配置 Web 服务器的起点。根据你的服务器配置，此文件很可能需要进行定制。<strong>如果你需要协助管理服务器，可以考虑使用 Laravel 官方提供的服务器管理和部署服务，如 <a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a>。</strong></p>
<p>请确保，像下面的配置一样，你的 Web 服务器将所有请求指向应用程序的 <code v-pre>public/index.php</code> 文件。绝不能把 <code v-pre>index.php</code> 文件移动到项目根目录，因为从项目根目录提供应用程序将会使许多敏感的配置文件暴露在公共互联网上：</p>
<div class="language-nginx line-numbers-mode" data-highlighter="prismjs" data-ext="nginx" data-title="nginx"><pre v-pre class="language-nginx"><code><span class="line"><span class="token directive"><span class="token keyword">server</span></span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">listen</span> <span class="token number">80</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">listen</span> [::]:80</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">server_name</span> example.com</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">root</span> /srv/example.com/public</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">add_header</span> X-Frame-Options <span class="token string">"SAMEORIGIN"</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">add_header</span> X-Content-Type-Options <span class="token string">"nosniff"</span></span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">index</span> index.php</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">charset</span> utf-8</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> /</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">try_files</span> <span class="token variable">$uri</span> <span class="token variable">$uri</span>/ /index.php?<span class="token variable">$query_string</span></span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> = /favicon.ico</span> <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">access_log</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">log_not_found</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> = /robots.txt</span>  <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">access_log</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">log_not_found</span> <span class="token boolean">off</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">error_page</span> <span class="token number">404</span> /index.php</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> ~ \.php$</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">fastcgi_pass</span> unix:/var/run/php/php8.2-fpm.sock</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">fastcgi_param</span> SCRIPT_FILENAME <span class="token variable">$realpath_root</span><span class="token variable">$fastcgi_script_name</span></span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">include</span> fastcgi_params</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">fastcgi_hide_header</span> X-Powered-By</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token directive"><span class="token keyword">location</span> ~ /\.(?!well-known).*</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token directive"><span class="token keyword">deny</span> all</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="frankenphp" tabindex="-1"><a class="header-anchor" href="#frankenphp"><span>FrankenPHP</span></a></h3>
<p><a href="https://frankenphp.dev/" target="_blank" rel="noopener noreferrer">FrankenPHP</a> 也可以用来服务 Laravel 应用程序。FrankenPHP 是用 Go 编写的现代 PHP 应用服务器。要使用 FrankenPHP 为 Laravel PHP 应用提供服务，您可以简单地调用其 <code v-pre>php-server</code> 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">frankenphp php-server <span class="token parameter variable">-r</span> public/</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>要利用 FrankenPHP 支持的更强大功能，例如其 <a href="https://learnku.com/docs/laravel/11.x/octane" target="_blank" rel="noopener noreferrer">Laravel Octane</a> 集成、HTTP/3、现代压缩技术或将 Laravel 应用打包为独立的二进制文件，请参阅 FrankenPHP 的 <a href="https://frankenphp.dev/docs/laravel/" target="_blank" rel="noopener noreferrer">Laravel 文档</a>。</p>
<h3 id="目录权限" tabindex="-1"><a class="header-anchor" href="#目录权限"><span>目录权限</span></a></h3>
<p>Laravel 需要写入 <code v-pre>bootstrap/cache</code> 和 <code v-pre>storage</code> 目录，因此你应确保 Web 服务器进程所有者有权限写入这些目录。</p>
<h2 id="优化" tabindex="-1"><a class="header-anchor" href="#优化"><span>优化</span></a></h2>
<p>在将应用程序部署到生产环境时，有多种文件应该被缓存，包括配置、事件、路由和视图。Laravel 提供了一个方便的单一 <code v-pre>optimize</code> Artisan 命令，可以缓存所有这些文件。这个命令通常应该作为应用程序部署过程的一部分被调用：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan optimize</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p><code v-pre>optimize:clear</code> 方法可以用来删除由 <code v-pre>optimize</code> 命令生成的所有缓存文件：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan optimize:clear</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>在接下来的文档中，我们将讨论由 <code v-pre>optimize</code> 命令执行的每个细粒度优化命令。</p>
<h3 id="缓存配置" tabindex="-1"><a class="header-anchor" href="#缓存配置"><span>缓存配置</span></a></h3>
<p>在将应用程序部署到生产环境时，应确保在部署过程中运行 <code v-pre>config:cache</code> Artisan 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan config:cache</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>这个命令会将 Laravel 的所有配置文件合并成一个缓存文件，这大大减少了框架在加载配置值时对文件系统进行的访问次数。</p>
<blockquote>
<p><strong>注意</strong><br>
如果您在部署过程中执行 <code v-pre>config:cache</code> 命令，您应确保只在配置文件中调用 <code v-pre>env</code> 函数。一旦配置被缓存，<code v-pre>.env</code> 文件将不会被加载，对 <code v-pre>.env</code> 变量的所有调用 <code v-pre>env</code> 函数将返回 <code v-pre>null</code>。</p>
</blockquote>
<h3 id="缓存事件" tabindex="-1"><a class="header-anchor" href="#缓存事件"><span>缓存事件</span></a></h3>
<p>在部署过程中，应该缓存应用程序的自动发现的事件到监听器映射。这可以通过在部署期间调用 <code v-pre>event:cache</code> Artisan 命令来完成：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan event:cache</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="缓存路由" tabindex="-1"><a class="header-anchor" href="#缓存路由"><span>缓存路由</span></a></h3>
<p>如果你正在构建一个包含许多路由的大型应用程序，应该确保在部署过程中运行 <code v-pre>route:cache</code> Artisan 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan route:cache</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>这个命令将所有的路由注册减少到缓存文件中的单个方法调用，当注册数百个路由时，可以提高路由注册的性能。</p>
<h3 id="缓存视图" tabindex="-1"><a class="header-anchor" href="#缓存视图"><span>缓存视图</span></a></h3>
<p>当将应用程序部署到生产环境时，你应该确保在部署过程中运行 <code v-pre>view:cache</code> Artisan 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan view:cache</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>这个命令预编译所有的 Blade 视图，因此它们不会在需求时编译，从而提高了返回视图的每个请求的性能。</p>
<h2 id="调试模式" tabindex="-1"><a class="header-anchor" href="#调试模式"><span>调试模式</span></a></h2>
<p><code v-pre>config/app.php</code> 配置文件中的调试选项决定了向用户显示的错误信息量。默认情况下，此选项设置为 <code v-pre>APP_DEBUG</code> 环境变量的值，该变量存储在您应用程序的 <code v-pre>.env</code> 文件中。</p>
<blockquote>
<p><strong>注意</strong><br>
<strong>在生产环境中，此值应始终为「false」。如果在生产中将 <code v-pre>APP_DEBUG</code> 变量设置为「true」，可能会向应用程序的最终用户暴露敏感配置值。</strong></p>
</blockquote>
<h2 id="健康检查路由" tabindex="-1"><a class="header-anchor" href="#健康检查路由"><span>健康检查路由</span></a></h2>
<p>Laravel 包括一个内置的健康检查路由，可用于监控应用程序的状态。在生产中，此路由可用于向运行时间监控器、负载均衡器或诸如 Kubernetes 之类的编排系统报告应用程序的状态。</p>
<p>默认情况下，健康检查路由在 <code v-pre>/up</code> 地址提供服务，并且如果应用程序无异常启动，将返回 200 HTTP 响应。否则，将返回 500 HTTP 响应。可以在应用程序的 <code v-pre>bootstrap/app</code> 文件中配置此路由的 URI：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token operator">-></span><span class="token function">withRouting</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token argument-name">web</span><span class="token punctuation">:</span> <span class="token constant">__DIR__</span><span class="token operator">.</span><span class="token string single-quoted-string">'/../routes/web.php'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token argument-name">commands</span><span class="token punctuation">:</span> <span class="token constant">__DIR__</span><span class="token operator">.</span><span class="token string single-quoted-string">'/../routes/console.php'</span><span class="token punctuation">,</span></span>
<span class="line">   <span class="token argument-name">health</span><span class="token punctuation">:</span> <span class="token string single-quoted-string">'/up'</span><span class="token punctuation">,</span> <span class="token comment">// [删除这一行]</span></span>
<span class="line">   health<span class="token punctuation">:</span> <span class="token string single-quoted-string">'/status'</span><span class="token punctuation">,</span> <span class="token comment">// [添加这一行]</span></span>
<span class="line"><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当对此路由发出 HTTP 请求时，Laravel 还将触发 <code v-pre>Illuminate\Foundation\Events\DiagnosingHealth</code> 事件，允许执行与应用程序相关的额外健康检查。在此事件的 <a href="https://learnku.com/docs/laravel/11.x/events" target="_blank" rel="noopener noreferrer">监听器</a> 中，可以检查应用程序的数据库或缓存状态。如果检测到应用程序存在问题，可以直接从监听器中抛出异常。</p>
<h2 id="使用-forge-vapor-轻松部署" tabindex="-1"><a class="header-anchor" href="#使用-forge-vapor-轻松部署"><span>使用 Forge / Vapor 轻松部署</span></a></h2>
<h4 id="laravel-forge" tabindex="-1"><a class="header-anchor" href="#laravel-forge"><span>Laravel Forge</span></a></h4>
<p>如果你没有准备好管理自己的服务器配置，或者不习惯配置运行健全的 Laravel 应用程序所需的各种服务，<a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a> 是一个绝佳的选择。</p>
<p>Laravel Forge 可以在各种基础设施提供商（如 DigitalOcean、Linode、AWS 等）创建服务器。此外，Forge 安装并管理构建健全 Laravel 应用程序所需的所有工具，如 Nginx、MySQL、Redis、Memcached、Beanstalk 等。</p>
<blockquote>
<p><strong>提示</strong><br>
想要一份完整的使用 Laravel Forge 部署的指南？请查看 <a href="https://bootcamp.laravel.com/deploying" target="_blank" rel="noopener noreferrer">Laravel Bootcamp</a> 和 Forge 在 <a href="https://laracasts.com/series/learn-laravel-forge-2022-edition" target="_blank" rel="noopener noreferrer">Laracasts 上的视频系列</a>。</p>
</blockquote>
<h4 id="laravel-vapor" tabindex="-1"><a class="header-anchor" href="#laravel-vapor"><span>Laravel Vapor</span></a></h4>
<p>如果想全无服务器的、自动扩展的部署平台，专为 Laravel 调优，请查看 <a href="https://vapor.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Vapor</a>。Laravel Vapor 是一个为 Laravel 设计的无服务器部署平台，由 AWS 提供支持。在 Vapor 上启动您的 Laravel 基础设施，并爱上无服务器的可扩展简便性。Laravel Vapor 由 Laravel 的创建者精心调整，以便与框架无缝合作，因此你以像平时一样继续编写 Laravel 应用程序。</p>
<blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/11.x/deploymentmd/16652" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/de...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/11.x/deploymentmd/16652" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/de...</a></p>
</blockquote>
</div></template>


